#include"Connection.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include"Protocol.hpp"
#include"Calculate.hpp"
#include<unistd.h>
using namespace Proctocol;
class Handler
{
    public:
    Handler(){}
    static void HandlerRequest(Connection* conn)
    {
        std::string& buffer=conn->GetInbuffer();
        Factory factory;
        auto req=factory.BuildRequest();
        std::string message;
        CalculateNs::Calculate cal;
        //解包
        while(Decode(buffer,&message))
        {
            //反序列化
            if(!req->Deserialize(message))
            continue;
            //业务处理
            auto resp=cal.Cal(req);
            //序列化
            std::string out;
            if(!resp->Serialize(&out))
            continue;
            //装包
            out=Encode(out);
            //发送
            conn->AddOutbuffer(out);
        }
        if(!conn->IsEmptyOutbuffer())
        {
            conn->_sender(conn);
        }
    }
    static void Recv(Connection* conn)
    {
        errno=0;
        char buffer[1024];
        while(true)
        {
            int n=recv(conn->GetFd(),buffer,sizeof(buffer)-1,0);
            if(n>0)
            {
                buffer[n]=0;
                conn->AddInbuffer(buffer);  
            }
            else
            {
                if(errno==EAGAIN)break;
                else if(errno==EINTR)continue;
                else
                {
                    conn->_excepter(conn);
                    return;
                }
            }
        }
        std::cout<<"sockfd#: "<<conn->GetFd()<<"\n"<<buffer<<std::endl;
        //报文读取完成，分析报文
        HandlerRequest(conn);
    }
    static void Send(Connection* conn)
    {
        errno=0;
        std::string& buffer=conn->GetOutbuffer();
        while(true)
        {
            int n=send(conn->GetFd(),buffer.c_str(),buffer.size(),0);
            if(n>=0)
            {
                buffer.erase(0,n);
                if(buffer.empty())break;
            }
            else
            {
                if(errno==EAGAIN)break;
                else if(errno==EINTR)continue;
                else
                {
                    conn->_excepter(conn);
                    return;
                }
            }
        }
        if(!conn->IsEmptyOutbuffer())
        conn->_R->EnableRecvSend(conn->GetFd(),true,true);
        else
        conn->_R->EnableRecvSend(conn->GetFd(),true,false);
    }
    static void Except(Connection* conn)
    {
        lg.LogMessage(Debug,"sockfd remove,who is %d\n",conn->GetFd());
        errno=0;
        conn->_R->RemoveConnection(conn->GetFd());
        conn->Close();
    }
    ~Handler(){}
    private:
};